package com.yeskery.nut.http.nio;

import com.yeskery.nut.core.NutException;
import com.yeskery.nut.core.ServerContext;
import com.yeskery.nut.core.ServerRequestConfiguration;
import com.yeskery.nut.core.SessionManager;
import com.yeskery.nut.http.BaseRequest;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;

/**
 * 基于 <b>NIO</b> 模式下的 {@link com.yeskery.nut.core.Request} 的实现，该类继承自 {@link BaseRequest}
 * @author sprout
 * @version 1.0
 * 2019-03-19 00:48
 */
public class NioRequest extends BaseRequest {

	/** 用于承载的输出字节数组 */
    private final byte[] bytes;

    /** Socket 通道对象 */
    private final SocketChannel channel;

	/**
	 * 构建一个 {@link NioRequest} 对象
     * @param channel Socket 通道对象
	 * @param bytes 字节数组
     * @param serverContext 服务上下文
	 * @param sessionManager session 管理器
     * @param serverRequestConfiguration 服务请求配置对象
	 */
	public NioRequest(SocketChannel channel, byte[] bytes, ServerContext serverContext, SessionManager sessionManager, ServerRequestConfiguration serverRequestConfiguration) {
        super(serverContext, sessionManager, serverRequestConfiguration);
        this.channel = channel;
        this.bytes = bytes;
        initialize();
    }

    @Override
    protected byte[] readRequestBytes() {
        return bytes;
    }

    @Override
    public String getRemoteAddress() {
        return getRemoteInetSocketAddress().getAddress().getHostAddress();
    }

    @Override
    public String getRemoteHost() {
        return getRemoteInetSocketAddress().getHostName();
    }

    @Override
    public int getRemotePort() {
        return getRemoteInetSocketAddress().getPort();
    }

    @Override
    public String getLocalAddress() {
        return getLocalInetSocketAddress().getAddress().getHostAddress();
    }

    @Override
    public String getLocalHost() {
        return getLocalInetSocketAddress().getHostName();
    }

    @Override
    public int getLocalPort() {
        return getLocalInetSocketAddress().getPort();
    }

    /**
     * 获取远程InetSocketAddress对象
     * @return 远程InetSocketAddress对象
     */
    private InetSocketAddress getRemoteInetSocketAddress() {
        try {
            return covertInetSocketAddress(channel.getRemoteAddress());
        } catch (IOException e) {
            throw new NutException("An Error Occurred While Obtain Remote Socket Address.", e);
        }
    }

    /**
     * 获取本地InetSocketAddress对象
     * @return 本地InetSocketAddress对象
     */
    private InetSocketAddress getLocalInetSocketAddress() {
        try {
            return covertInetSocketAddress(channel.getLocalAddress());
        } catch (IOException e) {
            throw new NutException("An Error Occurred While Obtain Local Socket Address.", e);
        }
    }
}
